<?php
/**
 * appRain CMF
 *
 * LICENSE
 *
 * This source file is subject to the MIT license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://www.opensource.org/licenses/mit-license.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@apprain.com so we can send you a copy immediately.
 *
 * @copyright  Copyright (c) 2010 appRain, Team. (http://www.apprain.com)
 * @license    http://www.opensource.org/licenses/mit-license.php MIT license
 *
 * HELP
 *
 * Official Website
 * http://www.apprain.com/
 *
 * Download Link
 * http://www.apprain.com/download
 *
 * Documents Link
 * http ://www.apprain.com/docs
 */


/**
 * Class to manage cookie
 *
 */
class appRain_Base_Modules_Definition extends appRain_Base_Objects
{
    public  $InformationSetCache = true;
    private $InformationSetSingleToneCache = array();

    public  $CategorySetCache = true;
    private $CategorySetSingleToneCache = array();

    public  $InterfaceBuilderCache = true;
    private $InterfaceBuilderSingleToneCache = array();

    public  $SiteSettingsCache = true;
    private $SiteSettingsSingleToneCache = array();

    public  $URIManagerCache = true;
    private $URIManagerSingleToneCache = array();

    public  $ProfileUserConfigCache = true;
    private $ProfileUserConfigSingleToneCache = array();

    public  $AddonCache = true;
    private $AddonSingleToneCache = array();

    private $SysConfigSingleToneCache =array();

    public  $ComponentCache = true;
    private $ComponentSingleToneCache = array();
    const COMPONENT_DEF_FILE_MAME = 'definition.xml';

    private $DBConfigSingleToneCache = array();

    const DEFINITION = 'definition';
    const INFO_XML_FILE = 'info.xml';

    public  $ext ='.xml';
    public  $cache_ext = 'arbt';
    public  $script_ext = '.php';
    private $cache_path = "";

    public $restrictedFieldName = Array('id','link_to','adminref','fkey','generic','type','entry_date','last_modified','threshold');

    /* Constructor */
    public function __construct()
    {
        $this->cache_path_manager();
    }

    /*==========================================================================================
                                        Theme List
    ==========================================================================================*/
    public function getThemeInfo($name=null)
    {
        if(!isset($name)){
            die('Theme name not specified');
        }
        if(is_array($name)){
            return null;
        }

        $defnitionpath = strtolower(VIEW_PATH . DS . $name . DS . self::DEFINITION . DS . self::INFO_XML_FILE);
        $dom = new DOMDocument();
        $dom->load($defnitionpath);

        $definition = array();
        $definition['name'] = $dom->getElementsByTagName('name')->item(0)->nodeValue;
        $definition['author'] = $dom->getElementsByTagName('author')->item(0)->nodeValue;
        $definition['author_uri'] = $dom->getElementsByTagName('author_uri')->item(0)->nodeValue;
        $definition['description'] = $dom->getElementsByTagName('description')->item(0)->nodeValue;
        $definition['image'] = $dom->getElementsByTagName('image')->item(0)->nodeValue;

        $definition['settings'] = "";
        if($dom->getElementsByTagName('settings')->item(0)){
            $definition['settings'] = $dom->getElementsByTagName('settings')->item(0)->nodeValue;
        }

        if($dom->getElementsByTagName('pagemanager_hooks')->item(0)){
            $pagemanager_hooks = $dom->getElementsByTagName('pagemanager_hooks')->item(0)->getElementsByTagName('hook_group');
            foreach($pagemanager_hooks as $hook_group){
                $hook_group_name = $hook_group->getAttribute('name');
                $definition['hooks'][$hook_group_name]['title'] = $hook_group->getAttribute('title');
                foreach($hook_group->getElementsByTagName('hook') as $hook){
                    $definition['hooks'][$hook_group_name]['list'][$hook->getAttribute('name')] = $hook->nodeValue;
                }
            }
        }
        return $definition;
    }

    /*==========================================================================================
                                        Component List
    ===========================================================================================*/
    public function getComponentList($soption=NULL)
    {
        if( empty($this->ComponentSingleToneCache)){
            $this->ComponentSingleToneCache = $this->parseComponentList();
        }
        return isset($soption) ? $this->ComponentSingleToneCache[$soption] : $this->ComponentSingleToneCache;
    }

    public function validateComponent($component)
    {
        $path = COMPONENT_PATH . DS . $component['name'] . DS . self::COMPONENT_DEF_FILE_MAME;
        if(file_exists($path)){
            return $path;
        }
        else{
            return false;
        }
    }

    public function parseComponentList()
    {
        $list = App::Load('Helper/Utility')->getDirLising(COMPONENT_PATH);
        $definitionlist = array();
        foreach( $list['dir'] as $component){
            if($defnitionpath=$this->validateComponent($component)){

                $dom = new DOMDocument();
                $dom->load($defnitionpath);
                $definition = array();
                $definition['error'] = array();
                $definition['name'] = UCFirst($dom->getElementsByTagName('name')->item(0)->nodeValue);
                $definition['namespace'] = $dom->getElementsByTagName('namespace')->item(0)->nodeValue;
                $definition['namespace'] = ($definition['namespace']=='auto')?$component['name']:$definition['namespace'];
                $definition['help'] = $dom->getElementsByTagName('help')->item(0)->nodeValue;

                if(trim($definition['help'])==""){
                    $definition['error'][] = $this->__("No help added for the component");
                }

                $definition['version'] = $dom->getElementsByTagName('version')->item(0)->nodeValue;
                $definition['uri'] = $dom->getElementsByTagName('uri')->item(0)->nodeValue;
                $definition['description'] = $dom->getElementsByTagName('description')->item(0)->nodeValue;
                $definition['author'] = $dom->getElementsByTagName('author')->item(0)->nodeValue;
                $definition['author_uri'] = $dom->getElementsByTagName('author_uri')->item(0)->nodeValue;
                $definition['checkfiles']['filepath'] = array();
                $definition['mypath'] = COMPONENT_PATH . DS . $component['name'];

                $path = $definition['mypath'] . DS . appRain_Base_component::BOOT_FILE . $this->script_ext;

                if(!file_exists($path)){
                    $definition['error'][] = "Your first boot file is not define. Expecting a file  {$path}";
                }

                $checkfiles = $dom->getElementsByTagName('checkfiles')->item(0);
                if($checkfiles){
                    $list = $checkfiles->getElementsByTagName('filepath');
                    if($list){
                        foreach( $list as $val){
                            $filepath = $definition['mypath'] . DS . $val->nodeValue;

                            if(!file_exists($filepath)){
                                $definition['error'][] = "File does not exists : {$filepath}";
                            }
                            else{
                                $definition['checkfiles']['filepath'] = $filepath;
                            }
                        }
                    }
                }

                if(empty($definition['error'])){
                    $definition['base_class_name'] = ucfirst($component['name']) . CDS . ucfirst($definition['namespace']);

                    App::Component($component['name'])->__data = $definition;
                    $definition['status'] = App::Component($component['name'])->Status();

                    if(appRain_Base_component::STATUS_ACTIVE === $definition['status']){
                        App::Component($component['name'])->init();
                    }
                }
                else{
                    $definition['status'] = appRain_Base_component::STATUS_INACTIVE;
                }

                $definitionlist[$definition['namespace']] = $definition;
            }
        }
        App::pageManager()->registerCallBacks();
        $this->registerThemeInfo();
        return $definitionlist;
    }

    /***** *****/
    private function registerThemeInfo()
    {
        $themleInfo = App::__Def()->getThemeInfo(App::Helper('Config')->siteInfo('theme'));

        if(isset($themleInfo['settings']) && $themleInfo['settings'] !=""){
            App::Module('Hook')->setHookName('InterfaceBuilder')
                           ->setAction("update_definition")
                           ->Register(get_class($this),"interfacebuilder_update_for_theme",$themleInfo);

            if($themleInfo['settings']!=""){
                App::Module('Hook')
                    ->setHookName('Sitesettings')
                    ->setAction("register_definition")
                    ->Register(get_class($this),"register_sitesettings_for_theme_defination");
            }
        }
    }

    public function interfacebuilder_update_for_theme($send,$themleInfo)
    {
        $themeName = App::Helper('Config')->siteInfo('theme',0);
        if($themeName){
            $themleInfo = App::__Def()->getThemeInfo($themeName);
            if($themleInfo['settings'] != ""){
                $send['developer']['child'][3]['items'][] = array(
                    "title"=>"Settings",
                    "link"=>"/admin/config/" . App::Helper('Utility')->getName($themleInfo['settings'])
                );
            }
        }
        return $send;
    }

    public function register_sitesettings_for_theme_defination()
    {
        $themeName = App::Helper('Config')->siteInfo('theme',0);
        $srcpaths = Array();
        if($themeName){
            $themleInfo = App::__Def()->getThemeInfo($themeName);
            $srcpaths[] = VIEW_PATH . DS . App::Helper('Config')->siteInfo('theme') . DS . "definition/{$themleInfo['settings']}";
        }
        return array('filepaths'=>$srcpaths);
    }
    /**** ****/
    /*==========================================================================================
                                        sysConfig
    ===========================================================================================*/
    public function sysConfig($soption = NULL)
    {
        if( empty($this->SysConfigSingleToneCache)){
            $this->SysConfigSingleToneCache = $this->parsesysConfigDefinition();
        }
        return isset($soption) ? $this->SysConfigSingleToneCache[$soption] : $this->SysConfigSingleToneCache;
    }

    private function parsesysConfigDefinition()
    {
        $file_path = CONFIG_PATH . DS . "config" . $this->ext;

        //Halt if information set is not exists
        if(!file_exists($file_path)){
            pre( "Configuration file missing  <br /> #Path: {$file_path}");
        }

        $definition = array();
        $dom = new DOMDocument();
        $dom->load($file_path);

        $base = $dom->getElementsByTagName('Configuration')
            ->item(0)
            ->getElementsByTagName('base')
            ->item(0);

        $definition['APPRAINVERSION'] = $base->getElementsByTagName('appRainversion')
            ->item(0)
            ->nodeValue;

        $definition['APPRAINLICENSEKEY'] = $base->getElementsByTagName('appRainLicenseKey')
            ->item(0)
            ->nodeValue;

        $options = $dom->getElementsByTagName('Configuration')
            ->item(0)
            ->getElementsByTagName('options')
            ->item(0)
            ->getElementsByTagName('option');

        foreach( $options as $val ){
            $nodevalue = ($val->getElementsByTagName('flag')->item(0)->nodeValue == 0) 
                ? $val->getElementsByTagName('value')->item(0)->nodeValue : $val->getElementsByTagName('default')->item(0)->nodeValue;

            switch(strtolower($val->getAttribute('type'))){
                case "string" : 
                    $definition[$val->getAttribute('name')] = "{$nodevalue}";
                    break;
                case "boolean" : 
                    $definition[$val->getAttribute('name')] = (strtolower($nodevalue) == 'yes') ? true : false;
                    break;
                default : 
                    $definition[$val->getAttribute('name')] = $nodevalue;
            }
        }
        return $definition;
    }

    /*==========================================================================================
                                        Database config
    ===========================================================================================*/
    public function getDBConfig($key=NULL, $cName=appRain_Base_Abstract::PRIMARY)
    {
        if(!isset($this->DBConfigSingleToneCache[$cName])){ 
            $dom = new DOMDocument();
            $dom->load(DATABASE_PATH . DS . 'database' . $this->ext);

            $connections = $dom->getElementsByTagName('connections')->item(0)->getElementsByTagName('connection');

            foreach( $connections as $conn ){
                if( $conn->getElementsByTagName('active')->item(0)->nodeValue == 1 
                    &&
                    strtolower($conn->getElementsByTagName('cname')->item(0)->nodeValue) ==  strtolower($cName)
                ){
                $dataConf = array (
                    'cname' => $conn->getElementsByTagName('cname')->item(0)->nodeValue,
                    'type' => $conn->getElementsByTagName('type')->item(0)->nodeValue,
                    'charset' => $conn->getElementsByTagName('charset')->item(0)->nodeValue,
                    'prefix' => $conn->getElementsByTagName('prefix')->item(0)->nodeValue,
                    'host' => $conn->getElementsByTagName('host')->item(0)->nodeValue,
                    'dbname' => $conn->getElementsByTagName('dbname')->item(0)->nodeValue,
                    'username' => $conn->getElementsByTagName('username')->item(0)->nodeValue,
                    'password' => $conn->getElementsByTagName('password')->item(0)->nodeValue
                    );
                    $this->DBConfigSingleToneCache[$cName] = $dataConf;
                }
            }
        }
        return  isset($this->DBConfigSingleToneCache[$cName][$key]) 
            ? $this->DBConfigSingleToneCache[$cName][$key] : $this->DBConfigSingleToneCache[$cName];
    }

    /*==========================================================================================
                                        Addons
    ===========================================================================================*/
    public function getAddons()
    {
        if( empty($this->AddonSingleToneCache)){
            $this->cache_path = ADDON_CACHE_PATH;

            // Read Cache
            $definition = ($this->cache_exists("addons")) ? $this->read_cache("addons") : $this->parseAddons();

            // Set Single tone cache
            $this->AddonSingleToneCache = $definition;

            // Create Physical cache
            if( app::__def()->sysConfig('ADDON_CACHE') ){
                if(!$this->cache_exists("addons")){
                    $this->do_cache($definition, "addons");
                }
            }
        }

       // Return defination
        return $this->AddonSingleToneCache;
    }

    private function parseAddons()
    {
        $file_path = ADDON_PATH ;

        //Halt if information set is not exists
        if(!file_exists($file_path)){
            pre( "Addons defination file missing  <br /> #Path: {$file_path}");
        }

        $definition = array();

        $list = App::Load('Helper/Utility')->getDirLising($file_path);

        $ptr = 0;
        while(list($key,$def) = each($list['file'])){
            if(strstr($def['name'],$this->ext) && $def['name'] != "addons{$this->ext}"){
                if($ptr == 0){
                    $list['file'][]['name'] = $def['name'];
                    $def['name'] = "addons{$this->ext}";
                }

                $dom = new DOMDocument();
                $dom->load($file_path . DS . $def['name'] );

                $addons = $dom->getElementsByTagName('Addons')->item(0)->getElementsByTagName('addon');

                foreach( $addons as $addon){
                    $status = $addon->getElementsByTagName('status')->item(0)->nodeValue;
                    if( $status == 'Active'){
                        $name = $addon->getAttribute('name');
                        $definition[$name]['title'] = $addon->getElementsByTagName('title')->item(0)->nodeValue;
                        $definition[$name]['code'] = $addon->getElementsByTagName('code')->item(0)->nodeValue;
                        $definition[$name]['load'] = $addon->getElementsByTagName('load')->item(0)->nodeValue;
                        $definition[$name]['layouts'] = $addon->getElementsByTagName('layouts')->item(0)->nodeValue;
                        $definition[$name]['layouts_except'] = $addon->getElementsByTagName('layouts_except')->item(0)->nodeValue;
                        $definition[$name]['status'] = $status;
                        $definition[$name]['comments'] = $addon->getElementsByTagName('comments')->item(0)->nodeValue;

                        $js_srcs = $addon->getElementsByTagName('javascripts')->item(0)->getElementsByTagName('src');
                        foreach( $js_srcs as $js_src){
                            $definition[$name]['javascripts'][] = $js_src->nodeValue;
                        }

                        $style_sheets = $addon->getElementsByTagName('style_sheets')->item(0)->getElementsByTagName('link');
                        foreach( $style_sheets as $style_sheet){
                            $definition[$name]['style_sheets'][] = $style_sheet->nodeValue;
                        }
                    }
                }

                $ptr++;
            }
        }
        //------------------------------
        $hookResource = App::Module('Hook')->getHookResouce('Addon','register_addon');

        if(!empty($hookResource)){
            foreach($hookResource as $node){
                if(($class=$node['resource'][0])!="" && ($method=$node['resource'][1])!=""){
                    $defs = App::__obj($class)->$method($definition);
                    foreach($defs as $def){
                        $hdef = $this->readaddonsfromhook($def['path']);
                        if(is_array($hdef)){
                            $definition = array_merge($definition,$hdef);
                        }
                    }

                }
            }
        }
        //------------------------------
        return $definition;
      }

      public function readaddonsfromhook($file_path)
      {
            $dom = new DOMDocument();
            $dom->load($file_path);

            $addons = $dom->getElementsByTagName('Addons')->item(0)->getElementsByTagName('addon');

            foreach( $addons as $addon){
                $status = $addon->getElementsByTagName('status')->item(0)->nodeValue;
                if( $status == 'Active'){
                    $name = $addon->getAttribute('name');
                    $definition[$name]['title'] = $addon->getElementsByTagName('title')->item(0)->nodeValue;
                    $definition[$name]['code'] = $addon->getElementsByTagName('code')->item(0)->nodeValue;
                    $definition[$name]['load'] = $addon->getElementsByTagName('load')->item(0)->nodeValue;
                    $definition[$name]['layouts'] = $addon->getElementsByTagName('layouts')->item(0)->nodeValue;
                    $definition[$name]['layouts_except'] = $addon->getElementsByTagName('layouts_except')->item(0)->nodeValue;
                    $definition[$name]['status'] = $status;
                    $definition[$name]['comments'] = $addon->getElementsByTagName('comments')->item(0)->nodeValue;

                    $js_srcs = $addon->getElementsByTagName('javascripts')->item(0)->getElementsByTagName('src');
                    foreach( $js_srcs as $js_src){
                        $definition[$name]['javascripts'][] = $js_src->nodeValue;
                    }

                    $style_sheets = $addon->getElementsByTagName('style_sheets')->item(0)->getElementsByTagName('link');
                    foreach( $style_sheets as $style_sheet){
                        $definition[$name]['style_sheets'][] = $style_sheet->nodeValue;
                    }
                }
            }

            return $definition;
      }
    /*==========================================================================================
                                        Profile User Config
    ===========================================================================================*/
    public function getProfileUserConfigDefinition()
    {
        if( empty($this->ProfileUserConfigSingleToneCache))
        {
            $this->cache_path = PROFILEUSERCONFIG_CACHE_PATH;

            // Read Cache
            $definition = ($this->cache_exists("profileuserconfig")) ? $this->read_cache("profileuserconfig") : $this->parseProfileUserConfigDefinition();

            // Set Single tone cache
            $this->ProfileUserConfigSingleToneCache = $definition;

            // Create Physical cache
            if( app::__def()->sysConfig('PROFILE_USER_CONFIG_CACHE') ){
                if(!$this->cache_exists("profileuserconfig")){
                    $this->do_cache($definition, "profileuserconfig");
                }
            }
        }

       // Return defination
        return $this->ProfileUserConfigSingleToneCache;
    }

    private function parseProfileUserConfigDefinition()
    {
        $file_path = PROFILEUSERCONFIG_PATH;

        //Halt if information set is not exists
        if(!file_exists($file_path)){
            pre( "Profile User Config missing  <br /> #Path: {$file_path} <br /> #Tipe: Do not forget to set \"admin_tab\"");
        }

        $definition = Array();
        $dom = new DOMDocument();
        $dom->load($file_path . DS. "static_pages" . $this->ext);

        $prfileuserconfig = $dom->getElementsByTagName('PrfileUserConfig' )->item(0);

        // Read Predefine pages
        $pages = $prfileuserconfig->getElementsByTagName('static_pages')->item(0)->getElementsByTagName('page');
        foreach(  $pages as $page ){
            $definition['pages'][] = array(
                'name' => $page->getElementsByTagName('name')->item(0)->nodeValue,
                'title' => $page->getElementsByTagName('title')->item(0)->nodeValue,
                'content' => $page->getElementsByTagName('content')->item(0)->nodeValue
            );
        }

        $dom = new DOMDocument();
        $dom->load($file_path . DS. "settings" . $this->ext);

        $settings = $dom->getElementsByTagName('settings')->item(0)->getElementsByTagName('group');
        foreach(  $settings as $options )
        {
            $definition['settings'][] = array(
                'name' => $options->getElementsByTagName('name')->item(0)->nodeValue,
                'value' => $options->getElementsByTagName('value')->item(0)->nodeValue,
                'sort_order' => $options->getElementsByTagName('sort_order')->item(0)->nodeValue,
                'section' => $options->getElementsByTagName('section')->item(0)->nodeValue
            );
        }
        return $definition;
    }

    /*==========================================================================================
                                        URI Manager
    ===========================================================================================*/
    public function getURIManagerDefinition()
    {
        if( empty($this->URIManagerSingleToneCache)){
            $this->cache_path = URIMANAGER_CACHE_PATH;

            // Read Cache
            $definition = ($this->cache_exists("urimanager")) ? $this->read_cache("urimanager") : $this->parseURIManagerDefinition();

            // Set Single tone cache
            $this->URIManagerSingleToneCache = $definition;

            // Create Physical cache
            if( app::__def()->sysConfig('URI_MANAGER_CACHE') ){
                $definition['bootrouter']['type'] = isset($definition['bootrouter']['type']) ? $definition['bootrouter']['type'] : "Fixed";

                if(strtolower($definition['bootrouter']['type']) != 'auto'){
                    if(!$this->cache_exists("urimanager")){
                        $this->do_cache($definition, "urimanager");
                    }
                }
            }
        }

        // RUN Callbacks
        $DynamicallyChnagedDefiniton = App::__obj('Development_Callbacks')->_on_uri_definition_init($this->URIManagerSingleToneCache);
        if(is_array($DynamicallyChnagedDefiniton) && !empty($DynamicallyChnagedDefiniton)) $this->URIManagerSingleToneCache = $DynamicallyChnagedDefiniton;

        $hookResource = App::Module('Hook')->getHookResouce('URIManager','on_initialize');

        if(!empty($hookResource)){
            foreach($hookResource as $node){
                if(($class=$node['resource'][0])!="" && ($method=$node['resource'][1])!=""){
                    $r2 = isset($node['resource'][2]) ? $node['resource'][2] : null;
                    $DynamicallyChnagedDefiniton = App::__obj($class)->$method($this->URIManagerSingleToneCache,$r2);
                    if(is_array($DynamicallyChnagedDefiniton) && !empty($DynamicallyChnagedDefiniton)){
                        $this->URIManagerSingleToneCache = $DynamicallyChnagedDefiniton;
                    }
                }
            }
        }
        return $this->URIManagerSingleToneCache;
    }


    private function parseURIManagerDefinition()
    {
        $file_path = URIMANAGER_PATH;

        //Halt if information set is not exists
        if(!file_exists($file_path)){
            pre( "URI Manager missing  <br /> #Path: {$file_path}");
        }

        $definition = array();
        $dom = new DOMDocument();
        $dom->load($file_path . DS . "boot_router" . $this->ext);

        $bootrouter = $dom->getElementsByTagName('bootrouters' )
            ->item(0)
            ->getElementsByTagName('bootrouter');

        foreach( $bootrouter as $val ){
            $theme = (strtolower($val->getElementsByTagName('theme')->item(0)->nodeValue) == 'auto') ? "" : $val->getElementsByTagName('theme')->item(0)->nodeValue;

            if( strtolower($val->getElementsByTagName('type')->item(0)->nodeValue ) == 'fixed' ){
                $profileuser = $val->getElementsByTagName('profileuser')->item(0);
                $definition['bootrouter'] = Array(
                    'type' => $val->getElementsByTagName('type')->item(0)->nodeValue,
                    'domain' => $val->getElementsByTagName('domain')->item(0)->nodeValue,
                    'theme' => $theme,
                    'controller' => $val->getElementsByTagName('controller')->item(0)->nodeValue,
                    'action' => $val->getElementsByTagName('action')->item(0)->nodeValue
                );

                $profileuserRout  = Array(
                    'controller' => $profileuser->getElementsByTagName('controller')->item(0)->nodeValue,
                    'action' => $profileuser->getElementsByTagName('action')->item(0)->nodeValue 
                );
            }
            else if( (str_replace('www.','',App::Helper('Config')->getServerInfo('SERVER_NAME')) . App::getBaseUrl()) == str_replace('www.','',$val->getElementsByTagName('domain')->item(0)->nodeValue) )
            {
                $profileuser = $val->getElementsByTagName('profileuser')->item(0);
                $definition['bootrouter'] = Array(
                    'type' => $val->getElementsByTagName('type')->item(0)->nodeValue,
                    'domain' => $val->getElementsByTagName('domain')->item(0)->nodeValue,
                    'theme' => $theme,
                    'controller' => $val->getElementsByTagName('controller')->item(0)->nodeValue,
                    'action' => $val->getElementsByTagName('action')->item(0)->nodeValue
                );
                $profileuserRout  = Array(
                    'controller' => $profileuser->getElementsByTagName('controller')->item(0)->nodeValue,
                    'action' => $profileuser->getElementsByTagName('action')->item(0)->nodeValue 
                );
                break;
            }
        }

        if(!isset($definition['bootrouter'])){
            pre( "Boot Router is not define.<br />Check URI Manager : {$file_path}");
        }

        $dom = new DOMDocument();
        $dom->load($file_path . DS . "global_router" . $this->ext);

        $globalrouter = $dom->getElementsByTagName('globalrouter' )->item(0);
        $definition['globalrouter']['controller'] = $globalrouter->getElementsByTagName('controller')->item(0)->nodeValue;
        $definition['globalrouter']['action'] = $globalrouter->getElementsByTagName('action')->item(0)->nodeValue;

        # Page Router
        $dom = new DOMDocument();
        $dom->load($file_path . DS . "page_router" . $this->ext);

        $roles = $dom->getElementsByTagName('pagerouter' )->item(0)->getElementsByTagName('role' );
        foreach( $roles as $role )
        {
            if($role->getElementsByTagName('actual')->item(0) && $role->getElementsByTagName('virtual')->item(0))
            {
                $definition['pagerouter'][] =   array
                                                (
                                                    "actual" => explode("/",$role->getElementsByTagName('actual')->item(0)->nodeValue),
                                                    "virtual" => array($role->getElementsByTagName('virtual')->item(0)->nodeValue)
                                                );
            }
        }
        if(App::getUserStatusId()){
            if(isset($profileuserRout['controller']) && isset($profileuserRout['action'])){
               $definition['bootrouter'] = array_merge($definition['bootrouter'],$profileuserRout);
            }           
        }

        return $definition;
    }

    /*==========================================================================================
                                          SITE SETTING
    ============================================================================================*/
    public function getSiteSettingsDefinition()
    {
        if( empty($this->SiteSettingsSingleToneCache)){
            $this->cache_path = SITESETTINGS_CACHE_PATH;

            // Read Cache
            $definition = ($this->cache_exists("sitesettings")) ? $this->read_cache("sitesettings") : $this->parseSiteSettingsDefinition();

            // Set Single tone cache
            $this->SiteSettingsSingleToneCache = $definition;

            // Create Physical cache
            if( app::__def()->sysConfig('SITE_SETTINGS_CACHE') ){
                if(!$this->cache_exists("sitesettings")){
                    $this->do_cache($definition, "sitesettings");
                }
            }
        }

        return $this->parseSiteSettingsDefinition();
    }

    private function parseSiteSettingsDefinition()
    {
        $file_path = SITESETTINGS_PATH;

        //Halt if information set is not exists
        if(!file_exists($file_path)){
            pre( "Site Settings missing  <br /> #Path: {$file_path} <br /> #Tipe: Do not forget to set \"admin_tab\"");
        }

        $definition = Array();

        $list = App::Load('Helper/Utility')->getDirLising($file_path);

        $definition = Array();

        foreach( $list['file'] as $def ){
            if(strstr($def['name'],$this->ext)){
                $def = $this->parseSiteSettingByFile($file_path .  DS . $def['name']);
                $definition = array_merge($definition,$def);
            }
        }

        // Generate by hook
        $hookResource = App::Module('Hook')->getHookResouce('Sitesettings','register_definition');

        if(!empty($hookResource)){
            foreach($hookResource as $node){
                if(($class=$node['resource'][0])!="" && ($method=$node['resource'][1])!=""){
                    $_rtn_resources = App::__obj($class)->$method();

                    if(!empty($_rtn_resources)){
                        foreach($_rtn_resources['filepaths'] as $filepath){
                            $def = $this->parseSiteSettingByFile($filepath);

                            // Merge definition
                            $key = key($def);
                            if(isset($definition[$key])){
                                $definition[$key]['groups'] = array_merge($definition[$key]['groups'],$def[$key]['groups']);
                            }
                            else $definition = array_merge($definition,$def);
                        }
                    }
                }
            }
        }
        return $definition;
    }

    private function parseSiteSettingByFile($file_path)
    {
        $dom = new DOMDocument();

        $dom->load($file_path);

        $sections = $dom->getElementsByTagName('sections');
        $definition = Array();
        foreach($sections as $sectionkey => $section ){
            $section_title = $section->getElementsByTagName('base')
                ->item(0)
                ->getElementsByTagName('title')
                ->item(0)
                ->nodeValue;

            $section_name = $section->getElementsByTagName('base')
                ->item(0)
                ->getAttribute('name');

            $admin_tab = $section->getElementsByTagName('base')
                ->item(0)
                ->getElementsByTagName('admin_tab')
                ->item(0)
                ->nodeValue;

            $groups = $section->getElementsByTagName('groups')->item(0)->getElementsByTagName('group');

            foreach( $groups as $group ){
                    $gt = array();
                    $group_base = $group->getElementsByTagName('base')->item(0);
                    $gt['name'] = $group_base->getAttribute('name');
                    $gt['title'] = $group_base->getElementsByTagName('title')->item(0)->nodeValue;

                    // ACL
                    $acl = $group_base->getElementsByTagName('acl')
                        ->item(0)
                        ->getElementsByTagName('ugroup');

                    foreach(  $acl as $ugroup){
                         $gt['acl'][] = $ugroup->nodeValue;
                    }

                    $group_selections = $group->getElementsByTagName('selections')
                        ->item(0)
                        ->getElementsByTagName('selection');

                    foreach( $group_selections as $selection ){
                        $name = $selection->getElementsByTagName('name')->item(0);
                        $gt['selection'][$name->nodeValue]['title'] = $selection->getElementsByTagName('title')->item(0)->nodeValue;
                        $gt['selection'][$name->nodeValue]['type'] = $selection->getElementsByTagName('type')->item(0)->nodeValue;
                        $gt['selection'][$name->nodeValue]['default'] = $selection->getElementsByTagName('default')->item(0)->nodeValue;
                        $gt['selection'][$name->nodeValue]['hints'] = "";
                        if($selection->getElementsByTagName('hints')->item(0)){
                            $gt['selection'][$name->nodeValue]['hints'] = $selection->getElementsByTagName('hints')->item(0)->nodeValue;
                        }

                        $options = $selection->getElementsByTagName('options')->item(0);
                        $opts = array();
                        if($options){
                           foreach( $options->getElementsByTagName('option') as $option){
                               $opts[$option->getAttribute('value')] = $option->nodeValue;
                           }
                           $gt['selection'][$name->nodeValue]['options'] = $opts;
                        }
                    }

                    $definition[$section_name]['base']['title'] = $section_title;
                    $definition[$section_name]['base']['admin_tab'] = $admin_tab;
                    $definition[$section_name]['base']['name'] = $gt['name'];
                    $definition[$section_name]['groups'][$gt['name']] = $gt;
            }
        }

        return $definition;
    }

    /*==========================================================================================
                                          WSDL Type
    ============================================================================================*/
    public function WSDLType()
    {
       return $this->parseWSDLType();
    }

    private function parseWSDLType()
    {
        $file_path = WSDL_PATH;

        if(!file_exists($file_path)){
            pre( "WSDL Directory missing  <br /> #Path: {$file_path}");
        }

        $list = App::Load('Helper/Utility')->getDirLising($file_path);

        $defDom = new DOMDocument();
        $types = $defDom->createElement ('types');
        $types = $defDom->appendChild($types);

        $schema = $defDom->createElement ('schema');
        $schema = $types->appendChild ($schema);

       /* $import = $defDom->createElement ('import');
        $import = $schema->appendChild ($import);
        $import->setAttribute("namespace","http://schemas.xmlsoap.org/soap/encoding/");
        $import->setAttribute("schemaLocation","http://schemas.xmlsoap.org/soap/encoding/");*/

        foreach( $list['file'] as $defkey => $def ){
            if(strstr($def['name'],$this->ext)){
                $dom = new DOMDocument();
                $dom->load($file_path . DS . $def['name'] );

                $types = $dom->getElementsByTagName('complexType');
                foreach( $types as $type){
                    $domType = $defDom->importNode($type, true);
                    $schema->appendChild($domType);
                }
            }
        }

        // Clear data
        unset($schema);
        unset($dom);

        return ($defDom->getElementsByTagName('types')->item(0));
    }

    /*==========================================================================================
                                          INTERFACE BUILDER
    ============================================================================================*/
    public function getInterfaceBuilderDefinition()
    {
        if( empty($this->InterfaceBuilderSingleToneCache)){
            $this->cache_path = INTERFACEBUILDER_CACHE_PATH;

            // Read Cache
            $definition = ($this->cache_exists("interfacebuilder")) ? $this->read_cache("interfacebuilder") : $this->parseInterfaceBuilderDefinition();

            // Set Single tone cache
            $this->InterfaceBuilderSingleToneCache = $definition;

            // Create Physical cache
            if( app::__def()->sysConfig('INTERFACE_BUILDER_CACHE') ){
                if(!$this->cache_exists("interfacebuilder")){
                    $this->do_cache($definition, "interfacebuilder");
                }
            }
        }

        // Return defination
        return $this->InterfaceBuilderSingleToneCache;
    }

    private function parseInterfaceBuilderDefinition()
    {
        $file_path = INTERFACEBUILDER_PATH;

        //Halt if information set is not exists
        if(!file_exists($file_path)){
            pre( "Interfacebuilder missing  <br /> #Path: {$file_path} <br /> #Tipe: Do not forget to set \"admin_tab\"");
        }

        $list = App::Load('Helper/Utility')->getDirLising($file_path);
        $interfacebuilder_def = Array();

        // General from defintion inside
        foreach( $list['file'] as $def ){
            if(strstr($def['name'],$this->ext)){
                $definition = $this->parseEachInterfaceBuilderDefintionFile($file_path . DS . $def['name']);
                $interfacebuilder_def = array_merge($interfacebuilder_def,$definition);
            }
        }

        $hookResource = App::Module('Hook')->getHookResouce('InterfaceBuilder','register_definition');
        if(!empty($hookResource)){
            foreach($hookResource as $node){
                if(($class=$node['resource'][0])!="" && ($method=$node['resource'][1])!=""){
                    $_rtn_resources = App::__obj($class)->$method();

                    if(!empty($_rtn_resources)){
                        foreach($_rtn_resources['filepaths'] as $filepath){
                            $definition = $this->parseEachInterfaceBuilderDefintionFile($filepath);
                            $interfacebuilder_def = array_merge($interfacebuilder_def,$definition);
                        }
                    }
                }
            }
        }

        $hookResource = App::Module('Hook')->getHookResouce('InterfaceBuilder','update_definition');
        if(!empty($hookResource)){
            foreach($hookResource as $node){
                if(($class=$node['resource'][0])!="" && ($method=$node['resource'][1])!=""){
                    $_rtn_resources = App::__obj($class)->$method($interfacebuilder_def,null);

                    if(isset($_rtn_resources) && is_array($_rtn_resources) && !empty($_rtn_resources)){
                        $interfacebuilder_def = $_rtn_resources;
                    }
                }
            }
        }

        return $this->sort_menu($interfacebuilder_def);
    }

    private function sort_menu($definition)
    {
        try{
            foreach($definition as &$ma){
                $tmp[] = &$ma['parent']["sort_order"];
            }

            array_multisort($tmp, $definition);

            return $definition;
        }
        catch(AppException $err){
            return $definition;
        }
    }

    private function parseEachInterfaceBuilderDefintionFile($file_path)
    {
        if(!file_exists($file_path)) return Array();

        $definition = Array();
        $dom = new DOMDocument();
        $dom->load($file_path);

        /* Parse Category set defination*/
        $navigations = $dom->getElementsByTagName('navigation');
        foreach($navigations as $navigation){
            // Parse Parent
            $parent = $navigation->getElementsByTagName('parent')->item(0);
            $nav_name = $navigation->getAttribute('name');
            $definition[$nav_name]['parent']['title'] = $parent->getElementsByTagName('title')->item(0)->nodeValue;
            $definition[$nav_name]['parent']['action'] = $parent->getElementsByTagName('action')->item(0)->nodeValue;
            $definition[$nav_name]['parent']['sort_order'] = $parent->getElementsByTagName('sort_order')->item(0)->nodeValue;
            $definition[$nav_name]['parent']['icon'] = '';
            if($parent->getElementsByTagName('icon')->item(0)){
                $definition[$nav_name]['parent']['icon'] = $parent->getElementsByTagName('icon')->item(0)->nodeValue;
            }
            $definition[$nav_name]['parent']['submenu']= array();
            if($parent->getElementsByTagName('submenu')->item(0)){
                $items = $parent->getElementsByTagName('submenu')->item(0)->getElementsByTagName('item');
                foreach($items as $key=>$item){
                    $definition[$nav_name]['parent']['submenu'][] = array(
                        "title"=>$item->getElementsByTagName('title')->item(0)->nodeValue,
                        "link"=>$item->getElementsByTagName('link')->item(0)->nodeValue
                    );
                    if($item->getAttribute('type') == 'multiple'){
                        $childitem = $item->getElementsByTagName('childitem');
                        foreach($childitem as $ckey=>$citem){
                            $definition[$nav_name]['parent']['submenu'][$key]['child'][] = array(
                                "title"=>$citem->getElementsByTagName('title')->item(0)->nodeValue,
                                "link"=>$citem->getElementsByTagName('link')->item(0)->nodeValue
                            );
                        }
                    }
                }
            }

            $acl_groups = $parent->getElementsByTagName('acl')->item(0)->getElementsByTagName('group');
            foreach( $acl_groups as $acl_group){
                $definition[$nav_name]['parent']['acl'][] = $acl_group->nodeValue;
            }

            // Parse Child
            $children = $navigation->getElementsByTagName('child');
            foreach( $children as $child ){
                $menu_arr = array();
                $menus = $child->getElementsByTagName('menu');
                foreach( $menus as $menu){
                    $items = $menu->getElementsByTagName('items')->item(0)->getElementsByTagName('item');
                    $menu_items = array();
                    foreach( $items as $item ){
                        $menu_items[] = array(
                            'title' => $item->getElementsByTagName('title')->item(0)->nodeValue,
                            'link' => $item->getElementsByTagName('link')->item(0)->nodeValue
                        );
                    }

                    $adminicon = array();
                    if($child->getElementsByTagName('adminicon')->item(0)){
                        $adminicon['type'] = $menu->getElementsByTagName('adminicon')->item(0)->getElementsByTagName('type')->item(0)->nodeValue;
                        $adminicon['location'] = $menu->getElementsByTagName('adminicon')->item(0)->getElementsByTagName('location')->item(0)->nodeValue;
                    }
                    $menu_arr[] = array('title' => $menu->getElementsByTagName('title')->item(0)->nodeValue,"items"=>$menu_items,'adminicon'=>$adminicon);

                }
                $definition[$nav_name]["child"] = $menu_arr;
            }
        }

        return $definition;
    }

    /*==========================================================================================
                                          CATAGORY SET
    ============================================================================================*/
    public function getCategorySetPathList()
    {
        $handaller = App::Module('Hook')->getHandler('CategorySet','register_definition');
        $data = array(CATEGORYSET_PATH);
        foreach($handaller as $val){
            $data[] = dirname($val[0]['path']);
        }

        return $data;
    }
    /**
     * Read Category Set List
     */
    public function getCategorySetList()
    {
        $list = App::Helper('Utility')->getDirLising($this->getCategorySetPathList());
        $tmp = Array();
        if(isset($list['file'])){
            foreach( $list['file'] as $val ){
                $ext = App::Helper('Utility')->getExt($val['name']);
                if(".{$ext}" == $this->ext){
                    array_push($tmp,App::Helper('Utility')->getName($val['name']));
                }
            }
        }
        return array_unique($tmp);
    }

    /**
     * Read information set definition
     *
     * @parameter type string
     * @return array
     */
    public function getCategorySetDefinition( $type = NULL)
    {
        if( !isset($this->CategorySetSingleToneCache[$type]))
        {
            $this->cache_path = CATEGORYSET_CACHE_PATH;

            // Read Cache
            $definition = ($this->cache_exists($type)) ? $this->read_cache($type) : $this->parseCategorySetdefination( $type );

            // Set Single tone cache
            $this->CategorySetSingleToneCache[$type] = $definition;

            // Create Physical cache
            if( app::__def()->sysConfig('CATEGORY_SET_CACHE') ){
                if(!$this->cache_exists($type)){
                    $this->do_cache($definition, $type);
                }
            }
        }

        // Return defination
        return $this->CategorySetSingleToneCache[$type];
    }

    private function parseCategorySetdefination($type = NULL)
    {
        $file_path = CATEGORYSET_PATH . DS . $type . $this->ext;

        //Halt if information set is not exists
        if(!file_exists($file_path)){
            $file_path = "";
            $hookResource = App::Module('Hook')->getHookResouce('CategorySet','register_definition');
            if(!empty($hookResource)){
                foreach($hookResource as $node){
                    if(($class=$node['resource'][0])!="" && ($method=$node['resource'][1])!=""){
                        $_rtn_resources = App::__obj($class)->$method();
                        if(!empty($_rtn_resources)){
                            foreach($_rtn_resources as $res){
                                if($type== $res['type'])
                                {
                                   $file_path = $res['path'];
                                }
                            }
                        }
                    }
                }
            }
            if($file_path == "")pre( "Category set is missing for  \"{$type}\" <br /> #Path: development/core/category_set/{$type}.xml <br /> #Tipe: Do not forget to set \"admin_tab\"");
        }

         $definition = array();
        $dom = new DOMDocument();
        $dom->load($file_path);

        /* Parse Category set defination*/
        $base = $dom->getElementsByTagName('base');
        $definition['version'] = $base->item(0)->getElementsByTagName("version")->item(0)->nodeValue;
        $definition['lastupdate'] = $base->item(0)->getElementsByTagName("lastupdate")->item(0)->nodeValue;
        $definition['title'] = $base->item(0)->getElementsByTagName("title")->item(0)->nodeValue;
        $definition['admin_tab'] = $base->item(0)->getElementsByTagName("admin_tab")->item(0)->nodeValue;
        $definition['description'] = $base->item(0)->getElementsByTagName("description")->item(0)->nodeValue;
        $definition['image']['status'] = $base->item(0)->getElementsByTagName("image")->item(0)->getElementsByTagName("status")->item(0)->nodeValue;
        $definition['image']['type'] = $base->item(0)->getElementsByTagName("image")->item(0)->getElementsByTagName("type")->item(0)->nodeValue;
        $definition['haschild'] = $base->item(0)->getElementsByTagName("haschild")->item(0)->nodeValue;
        $definition['generic']['status'] = $base->item(0)->getElementsByTagName("generic")->item(0)->getElementsByTagName("status")->item(0)->nodeValue;
        $definition['generic']['title'] = $base->item(0)->getElementsByTagName("generic")->item(0)->getElementsByTagName("title")->item(0)->nodeValue;

        // Search informaton
        $search = $dom->getElementsByTagName("sreach")->item(0);
        $definition['search'] = Array();
        if($search)
        {
            $definition['search']['status'] = $search->getElementsByTagName('status')->item(0)->nodeValue;
            $definition['search']['field-selected'] = $search->getElementsByTagName('field-selected')->item(0)->nodeValue;
            $definition['search']['parma-link']['type'] = $search->getElementsByTagName('parma-link')->item(0)->getElementsByTagName('type')->item(0)->nodeValue;
            $definition['search']['parma-link']['uri'] = $search->getElementsByTagName('parma-link')->item(0)->getElementsByTagName('uri')->item(0)->nodeValue;
        }
        return $definition ;

    }
    /*==========================================================================================
                                          INFORMATION SET
    ============================================================================================*/

     public function getInformationSetPathList()
    {
        $handaller = App::Module('Hook')->getHandler('InformationSet','register_definition');
        $data = array(INFORMATIONSET_PATH);
        foreach($handaller as $val){
            $data[] = dirname($val[0]['path']);
        }

        return $data;
    }

    /**
     * Read Category Set List
     */
    public function getInformationSetList()
    {
        $list = App::Helper('Utility')->getDirLising($this->getInformationSetPathList());
        $tmp = Array();
        foreach( $list['file'] as $val ){
            $ext = App::Helper('Utility')->getExt($val['name']);
            if(".{$ext}" == $this->ext){
                array_push($tmp,App::Helper('Utility')->getName($val['name']));
            }
        }
        return $tmp;
    }
    /**
     * Read information set definition
     *
     * @parameter type string
     * @return array
     */
    public function getInformationSetDefinition($type = '')
    {
        if( !isset($this->InformationSetSingleToneCache[$type])){
            $this->cache_path = INFORMATIONSET_CACHE_PATH;

            $definition = ($this->cache_exists($type)) ? $this->read_cache($type) : $this->parseInformationsetdefination( $type );

            // Create Single Tone cache
            $this->InformationSetSingleToneCache[$type] = $definition;

            // Create Physical cache
            if( app::__def()->sysConfig('INFORMATION_SET_CACHE') ){
                if(!$this->cache_exists($type)){
                    $this->do_cache($definition, $type);
                }

            }
        }
        return  $this->InformationSetSingleToneCache[$type] ;
    }

    /**
     * Parse Information Set defination
     *
     * @parameter type string
     * @return Array
     */
    private function parseInformationsetdefination($type = '')
    {
        $file_path = INFORMATIONSET_PATH . DS . $type . $this->ext;

        if(!file_exists($file_path)){
            $file_path = "";
            $hookResource = App::Module('Hook')->getHookResouce('InformationSet','register_definition');
            if(!empty($hookResource)){
                foreach($hookResource as $node){if(($class=$node['resource'][0])!="" && ($method=$node['resource'][1])!="")
                    {
                        $_rtn_resources = App::__obj($class)->$method();
                        if(!empty($_rtn_resources)){
                            foreach($_rtn_resources as $res)
                            {
                                if($type== $res['type'])
                                {
                                   $file_path = $res['path'];
                                }
                            }
                        }
                    }
                }
            }

            if($file_path == ""){
                pre( "Information set is missing for  \"{$type}\" <br /> #Path: development/core/information_set/{$type}.xml <br /> #Tipe: Do not forget to set \"admin_tab\"");
            }
        }
        $dom = new DOMDocument();
        $dom->load($file_path);
        $definition = array();

        ## Read base section
        $base = $dom->getElementsByTagName('base');
        // Information Set Version
        $definition['base']['version'] = $base->item(0)->getElementsByTagName("version")->item(0)->nodeValue;

        // Last Update
        $definition['base']['lastupdate'] = $base->item(0)->getElementsByTagName("lastupdate")->item(0)->nodeValue;

        // Information Set title
        $definition['base']['title'] = $base->item(0)->getElementsByTagName("title")->item(0)->nodeValue;

        // Admin tab to be rendered
        $definition['base']['admin_tab'] = $base->item(0)->getElementsByTagName("admin_tab")->item(0)->nodeValue;

        // Read addons
        if( $base->item(0)->getElementsByTagName('addons')->item(0))
        {
            $parameters =  $base->item(0)->getElementsByTagName('addons')->item(0)->getElementsByTagName('addon');
            foreach( $parameters as $parameter )
            {
              $definition['base']['addons'][] = $parameter->nodeValue;
            }
        } else $definition['addons'] = array();

        // Read parameters
        if( $base->item(0)->getElementsByTagName('parameters')->item(0)){
            $parameters =  $base->item(0)->getElementsByTagName('parameters')->item(0)->getElementsByTagName('parameter');
            foreach( $parameters as $parameter ){
              $definition['base']['parameters'][$parameter->getAttribute('name')] = $parameter->nodeValue;
            }
        } 
        else {
            $definition['parameters'] = array();
        }
        // Generic Field definition
        $generic_field = $base->item(0)->getElementsByTagName("generic-field");
        $definition['base']['generic_field']['enabled'] = $generic_field->item(0)->getElementsByTagName("enabled")->item(0)->nodeValue;
        $definition['base']['generic_field']['title'] = $generic_field->item(0)->getElementsByTagName("title")->item(0)->nodeValue;

        $definition['base']['generic_field']['validation'] = $this->readValidationData($generic_field->item(0));

        $definition['base']['generic_field']['type'] = $generic_field->item(0)->getElementsByTagName("type")->item(0)->nodeValue;
        $attributes = $generic_field->item(0)->getElementsByTagName("tag-attributes")->item(0)->getElementsByTagName("attribute");
        foreach( $attributes as $attribute){
            $definition['base']['generic_field']['tag-attributes'][$attribute->getAttribute('name')] = $attribute->nodeValue;
        }

        // Maximum Entry Definition
        $max_entry = $base->item(0)->getElementsByTagName("max_entry");
        $definition['base']['generic_field']['max_entry']['limit']= $max_entry->item(0)->getElementsByTagName("limit")->item(0)->nodeValue;
        $definition['base']['generic_field']['max_entry']['message']= $max_entry->item(0)->getElementsByTagName("message")->item(0)->nodeValue;

        // Search informaton
        $search = $base->item(0)->getElementsByTagName("sreach")->item(0);
        $definition['base']['search'] = Array();
        if($search){
            $definition['base']['search']['status'] = $search->getElementsByTagName('status')->item(0)->nodeValue;
            $definition['base']['search']['field-selected'] = $search->getElementsByTagName('field-selected')->item(0)->nodeValue;
            $definition['base']['search']['field-description'] = $search->getElementsByTagName('field-description')->item(0)->nodeValue;
            $definition['base']['search']['parma-link']['type'] = $search->getElementsByTagName('parma-link')->item(0)->getElementsByTagName('type')->item(0)->nodeValue;
            $definition['base']['search']['parma-link']['uri'] = $search->getElementsByTagName('parma-link')->item(0)->getElementsByTagName('uri')->item(0)->nodeValue;
        }

        ## Read Virtual fields
        $fields = $dom->getElementsByTagName('fields')->item(0)->getElementsByTagName('field');
        foreach($fields as $field){
            $fieldName = $field->getAttribute('name');
            if(in_array($fieldName,$this->restrictedFieldName)){
                pr($this->__("'{$fieldName}' can not be use as field name in Information Set: '{$type}'<br />(EAV Convension warning: 0001)"));
            }
            $definition['fields'][$fieldName] = $this->readInformationsetFieldDef($field);
        }

        return  $definition;
    }

    private function readValidationData($domobj=NULL)
    {
        try{
            $validationObj = $domobj->getElementsByTagName("validation")->item(0);
            $validationlist = Array();
            if($validationObj){
                if(!$validationObj->nodeValue){
                    return Array();
                }
                if($validationObj->getElementsByTagName("rule")->item(0)){
                    foreach($domobj->getElementsByTagName("rule") as $val){
                        $validationlist[] = $this->readValidationNode($val);
                    }
                }
                else{
                    $validationlist[] = $this->readValidationNode($validationObj);
                }
            }

            return $validationlist;
        }
        catch(Exception $Err){
            return Array();
        }

    }

    private function readValidationNode($domobj=NULL)
    {
        $nodeArr = Array();

        $nodeArr["type"] = $domobj->getElementsByTagName("type")->item(0)->nodeValue;
        $nodeArr["message"] = $domobj->getElementsByTagName("err-message")->item(0)->nodeValue;
        $list = $domobj->getElementsByTagName("list")->item(0);

        $listArr = Array();
        if($list){
            foreach($list->getElementsByTagName("val") as $val){
                $listArr[] = $val->nodeValue;
            }
        }
        $nodeArr["list"]  = $listArr;

        $options = $domobj->getElementsByTagName("rule-options")->item(0);
        $optionsArr = Array();
        if($options){
            foreach($options->getElementsByTagName("option") as $val){
                $optionsArr[$val->getAttribute("name")] = $val->nodeValue;
            }
        }
        $nodeArr["options"]  = $optionsArr;


        return $nodeArr;
    }

    /**
     * Read field object
     *
     * @parameter fieldobj DOM XML Object
     * @return Array
     */
    private function readInformationsetFieldDef( $fieldobj = NULL)
    {
       $defarr = array();

        if( $fieldobj->getElementsByTagName('title')->item(0)){
            $defarr['title'] = $fieldobj->getElementsByTagName('title')->item(0)->nodeValue;
        } else $defarr['title'] = "";

        if( $fieldobj->getElementsByTagName('searchable')->item(0)){
            $defarr['searchable'] = $fieldobj->getElementsByTagName('searchable')->item(0)->nodeValue;
        } else $defarr['searchable'] = "No";

        if( $fieldobj->getElementsByTagName('selected')->item(0)){
            $defarr['selected'] = $fieldobj->getElementsByTagName('selected')->item(0)->nodeValue;
        } else $defarr['selected'] = "";

        if($fieldobj->getElementsByTagName('hints')->item(0)){
             $defarr['hints'] = $fieldobj->getElementsByTagName('hints')->item(0)->nodeValue;
        } else $defarr['hints'] = "";

        if( $fieldobj->getElementsByTagName('type')->item(0) ){
            $defarr['type'] = $fieldobj->getElementsByTagName('type')->item(0)->nodeValue;
        } else $defarr['type'] = "";

        if( ($fieldobj->getElementsByTagName('category_type')->item(0))){
            $defarr['category_type'] = $fieldobj->getElementsByTagName('category_type')->item(0)->nodeValue;
        }

        if( ($fieldobj->getElementsByTagName('informationset_type')->item(0))){
            $defarr['informationset_type'] = $fieldobj->getElementsByTagName('informationset_type')->item(0)->nodeValue;
        }


        $defarr['validation'] = $this->readValidationData($fieldobj);

        if( $fieldobj->getElementsByTagName('options')->item(0)){
            $options =  $fieldobj->getElementsByTagName('options')->item(0)->getElementsByTagName('option');
            foreach( $options as $option ){
               $defarr['options'][$option->getAttribute('value')] = $option->nodeValue;
            }
        }

        if( $fieldobj->getElementsByTagName('parameters')->item(0)){
            $parameters =  $fieldobj->getElementsByTagName('parameters')->item(0)->getElementsByTagName('parameter');
            foreach( $parameters as $parameter ){
               $defarr['parameters'][$parameter->getAttribute('name')] = $parameter->nodeValue;
            }
        } else $defarr['parameters'] = array();

        if( $fieldobj->getElementsByTagName('tag-attributes')->item(0)){
            $parameters =  $fieldobj->getElementsByTagName('tag-attributes')->item(0)->getElementsByTagName('attribute');
            foreach( $parameters as $parameter ){
               $defarr['tag-attributes'][$parameter->getAttribute('name')] = $parameter->nodeValue;
            }
        } else $defarr['tag-attributes'] = array();

        // Return in array
        return $defarr;
    }

    /*==========================================================================================
                                          PROCESS CACHE
    ============================================================================================*/
    private function do_cache( $data = NULL, $file_name = NULL)
    {
        $this->write_to_disc($this->encode($data),$file_name);
    }

    private function read_cache($file_name = NULL)
    {
        return $this->decoted($this->read_from_desk( $file_name));
    }

    function encode( $data = NULL )
    {
        return isset($data) ? serialize( $data ) : "";
    }

    function decoted( $data = NULL )
    {
        return isset($data) ? unserialize( $data ) : "";
    }

    function cache_exists( $pre_name = NULL)
    {
        return file_exists($this->cache_path . DS . "{$pre_name}.{$this->cache_ext}");
    }

    function read_from_desk( $pre_name = NULL)
    {
        $path = $this->cache_path . DS . "{$pre_name}.{$this->cache_ext}";

        if( file_exists($path)){
            $handle = fopen($path, "r");
            $contents = '';
            while (!feof($handle)) {
              $contents .= fread($handle, 8192);
            }
            fclose($handle);

            return $contents;
        }
        else{
            echo "Key not found '{$pre_name}'";
        }
    }

    function write_to_disc( $data = NULL, $pre_name = NULL)
    {
        $path = $this->cache_path . DS . "{$pre_name}.{$this->cache_ext}";

        if (!$handle = fopen($path, 'w')){
            echo "Can not write file($path)";
            exit;
        }

        if (fwrite($handle, $data) === FALSE){
            echo "Can not write file($path)";
            exit;
        }

        fclose($handle);
    }

    public function cache_path_manager()
    {
        if( !file_exists(CACHE) || !is_writeable(CACHE)){
            pre( "Cache path is not writeable or missibg   <br /> #Path: " . CACHE);
        }

        // Create Base cache
        if(!file_exists(TEMP)) mkdir(TEMP,0777);
        if(!file_exists(BACKUP)) mkdir(BACKUP,0777);
        if(!file_exists(BYTE_STREAM)) mkdir(BYTE_STREAM,0777);
        if(!file_exists(DATA)) mkdir(DATA,0777);
        if(!file_exists(DATA . DS . 'database')) mkdir(DATA . DS . 'database',0777);

        // Create Temporary Cache
        if(!file_exists(MODEL_CACHE_PATH)) mkdir(MODEL_CACHE_PATH,0777);
        if(!file_exists(REPORT_CACHE_PATH)) mkdir(REPORT_CACHE_PATH,0777);
        if(!file_exists(CATEGORYSET_CACHE_PATH)) mkdir(CATEGORYSET_CACHE_PATH,0777);
        if(!file_exists(INFORMATIONSET_CACHE_PATH)) mkdir(INFORMATIONSET_CACHE_PATH,0777);
        if(!file_exists(INTERFACEBUILDER_CACHE_PATH)) mkdir(INTERFACEBUILDER_CACHE_PATH,0777);
        if(!file_exists(ADDON_CACHE_PATH)) mkdir(ADDON_CACHE_PATH,0777);
        if(!file_exists(SITESETTINGS_CACHE_PATH)) mkdir(SITESETTINGS_CACHE_PATH,0777);
        if(!file_exists(URIMANAGER_CACHE_PATH)) mkdir(URIMANAGER_CACHE_PATH,0777);
        if(!file_exists(PROFILEUSERCONFIG_CACHE_PATH)) mkdir(PROFILEUSERCONFIG_CACHE_PATH,0777);
        if(!file_exists(LANGUAGE_CACHE_PATH)) mkdir(LANGUAGE_CACHE_PATH,0777);
        if(!file_exists(WSDL_CACHE_PATH)) mkdir(WSDL_CACHE_PATH,0777);
        if(!file_exists(COMPONENT_CACHE_PATH)) mkdir(COMPONENT_CACHE_PATH,0777);
    }
}